package cse.uta.edu;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

public class BEN {
	private JFrame frame;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // Set UI to current system appearance
					BEN window = new BEN();
					window.frame.setVisible(true);
					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	/**
	 * Create the application.
	 */
	public BEN() {
		initialize();
	}
	
	@SuppressWarnings("static-access")
	private void initialize() {
		//Frame
				frame = new JFrame("");// Creating Frame
				frame.setSize(1000,600);  // setBounds(int x co-ordinate, int y co-ordinate, int height, int width)
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setDefaultLookAndFeelDecorated(true);
				frame.setLocationRelativeTo(null);  // to position the window center on the screen
				frame.setTitle("BEN"); 
				frame.setLayout(new BorderLayout());
				frame.setVisible(true);
		//Variables	
			// Menu Bar Components
				JMenuBar menuBar = new JMenuBar();
				JMenu fileMenu = new JMenu(" File");
				JMenu helpMenu = new JMenu(" Help");	
				JMenuItem fileOpen = new JMenuItem();
				JMenuItem fileExit = new JMenuItem();
				JMenuItem helpAbout = new JMenuItem();
				final String aboutApplication = "Version 1.0";
				Font defaultfont = new Font("Tahoma", 1, 25);
				Font font = new Font("Serif", Font.ITALIC, 24);
				
			//ToolBar Components
				JToolBar toolBar = new JToolBar();
				JButton openFileBtn = new JButton();
				JButton newFileBtn = new JButton();
				JButton infoHelpBtn = new JButton();
				
			//Right Panel components
				JPanel sourceCodePanel = new JPanel();
				JPanel initialTestCasePanel = new JPanel();
				JPanel specificationPanel = new JPanel();
								
				JLabel sourceCodeLabel = new JLabel("Source code");
				
				final JTabbedPane mainTab = new JTabbedPane();
				final JTabbedPane innerSpecificationTab = new JTabbedPane();
				mainTab.add("Source Code",sourceCodePanel);
				mainTab.add("Input Parameter Model",innerSpecificationTab);
				mainTab.add("Initial Test Set",initialTestCasePanel);
				//innerSpecificationTab.setBorder(BorderFactory.createCompoundBorder((BorderFactory.createRaisedBevelBorder()), (BorderFactory.createLoweredBevelBorder())));
				innerSpecificationTab.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
				sourceCodePanel.add(sourceCodeLabel);
				initialTestCasePanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
				mainTab.addChangeListener(new ChangeListener(){

					@Override
					public void stateChanged(ChangeEvent e) {
						//to be implemented later
						
					}});
				
			//Panel
				JPanel leftPanel = new JPanel();
				JPanel rightPanel = new JPanel();
				//Panels declarations for Constraints, Parameters and input test case view
					JPanel parameterPanel = new JPanel();
					parameterPanel.setLayout(new BorderLayout());
					JPanel constraintsPanel = new JPanel();
					constraintsPanel.setLayout(new BorderLayout());
					initialTestCasePanel.setLayout(new BorderLayout());
					//Table logic
					final DefaultTableModel pTable = new DefaultTableModel();
					JTable parameterTable = new JTable(pTable);
					
					final DefaultTableModel constraintsTable = new DefaultTableModel();
					JTable tableConstraints = new JTable(constraintsTable);
					
					final DefaultTableModel testresultTable = new DefaultTableModel();
					JTable resultTable = new JTable(testresultTable);
					
					parameterTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
					
					final String[] pnameArray = new String[2]; // Declaring string array
					pnameArray[0] = "Parameter Name"; // initializing the array elements individually
					pnameArray[1] = "Parameter Value"; 
				//ScrollPane declaration		
					final JScrollPane parameterPane = new JScrollPane(parameterTable);
					parameterPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
					parameterPane.setViewportBorder(new CompoundBorder(new CompoundBorder(null, new EtchedBorder(EtchedBorder.LOWERED, null, null)), null));
					parameterPane.setToolTipText("Parameters and Values");
				
					final JScrollPane constraintsPane = new JScrollPane(tableConstraints);
					constraintsPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
					constraintsPane.setToolTipText("Constraints");
					
					JScrollPane initialTestPane = new JScrollPane(resultTable);
					initialTestPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
					initialTestPane.setToolTipText("Initial Test Set");
					initialTestPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
					
					parameterPanel.add(parameterPane);
					parameterPanel.setSize(200,100);
					//parameterPanel.setBorder(BorderFactory.createTitledBorder("Parameters"));
					
					constraintsPanel.add(constraintsPane);
					constraintsPanel.setSize(200,100);
					//constraintsPanel.setBorder(BorderFactory.createTitledBorder("Constraints"));
					
					innerSpecificationTab.add("Parameters",parameterPanel);
					innerSpecificationTab.add("Constraints",constraintsPanel);
					
					initialTestCasePanel.add(initialTestPane);
					
				
			//Left panel components
				JLabel treeHeaderLabel = new JLabel();
				DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
				DefaultMutableTreeNode sourceCode = new DefaultMutableTreeNode("Source Code");
				DefaultMutableTreeNode initialTestCase = new DefaultMutableTreeNode("Initial Test Set");
				DefaultMutableTreeNode inputparametermodel = new DefaultMutableTreeNode("Input Parameter Model");
				DefaultMutableTreeNode parameters = new DefaultMutableTreeNode("Parameters");
				DefaultMutableTreeNode constraints = new DefaultMutableTreeNode("Constraints");
				
				final JTree tree = new JTree(root);
				
			
				
			//JSplitPane
				JSplitPane splitPane = new JSplitPane();
				splitPane.setDividerLocation(180);
				splitPane.setDividerSize(3);
				splitPane.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10)); // Empty border for the split pane
			
							
		//Definition Logic
				
				//Menu items definition logic
				fileOpen.setText(" Open Input File ...");
				//fileOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("cse/uta/edu/Images/open_project_16.png")));
				//fileOpen.setIcon(getClass().getResource("cse/uta/edu/Images/open_project_16.png"));
				fileOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
						java.awt.event.KeyEvent.VK_O,
						java.awt.event.InputEvent.CTRL_MASK));
				fileOpen.addActionListener(new ActionListener() {

					@Override
					public void actionPerformed(ActionEvent e) {
						// function call
						
					}});
				fileOpen.setToolTipText("Click to open the file");
				
				fileExit.setText(" Exit");
				//fileExit.setIcon(new javax.swing.ImageIcon(getClass().getResource("cse/uta/edu/Images/exit.png")));
				fileExit.setToolTipText("Exit the Application");
				fileExit.addActionListener(new ActionListener(){

					@Override
					public void actionPerformed(ActionEvent e) {
						System.exit(0);
						
					}});
				
				helpAbout.setText(" About");
				//helpAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource(
						//"cse/uta/edu/Images/about.gif")));
				helpAbout.addActionListener(new ActionListener(){

					@Override
					public void actionPerformed(ActionEvent e) {
						JOptionPane.showMessageDialog(frame, aboutApplication);
						
					}});
				
			//adding the menu items to menu
				fileMenu.add(fileOpen);
				fileMenu.addSeparator();
				fileMenu.add(fileExit);
				helpMenu.add(helpAbout);
				fileMenu.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
				helpMenu.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
			//adding menu to menu bar
				menuBar.add(fileMenu);
				menuBar.add(helpMenu);				
				
			// addding menubar to the window
				frame.setJMenuBar(menuBar);
				
			//ToolBar Components
				toolBar.setFloatable(false);
				
				openFileBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
						"/cse/uta/edu/Images/open_project_24.png")));
				openFileBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1,
						1, 4));
				newFileBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
						"/cse/uta/edu/Images/new_project_24.png")));
				newFileBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1,
						1, 4));
				infoHelpBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource(
						"/cse/uta/edu/Images/help2.jpg")));
				infoHelpBtn.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1,
						1, 4));

				toolBar.addSeparator();
				toolBar.add(newFileBtn);
				toolBar.add(openFileBtn);
				toolBar.add(infoHelpBtn);

			//LeftPanel components definitions
				treeHeaderLabel.setText("System View");
				treeHeaderLabel.setHorizontalAlignment(SwingConstants.CENTER);
				treeHeaderLabel.setBorder(new CompoundBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED),new EmptyBorder(5,5,5,5)));
				
				root.add(sourceCode);
				root.add(inputparametermodel);
				root.add(initialTestCase);
				inputparametermodel.add(parameters);
				inputparametermodel.add(constraints);
				tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
				/* to be implemented later
				GroupLayout layout = new GroupLayout(leftPanel);
				leftPanel.setLayout(layout);
				*/
				
			// Tree to Tab reflection logic -- when a node is selected on Tree, corresponding tab will become active
				tree.addTreeSelectionListener(new TreeSelectionListener(){

					@Override
					public void valueChanged(TreeSelectionEvent e) {
						DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
						if(selectedNode.isLeaf())
						{
							String nodeSelected = selectedNode.toString();
							if (nodeSelected == "Source Code" && mainTab.getSelectedIndex()!=0)
							{
								mainTab.setSelectedIndex(0);
							}
							if(nodeSelected == "Initial Test Case" && mainTab.getSelectedIndex()!=1)
							{
								mainTab.setSelectedIndex(1);
							}
							
							if(nodeSelected == "Parameters")
							{
								mainTab.setSelectedIndex(2);
								innerSpecificationTab.setSelectedIndex(0);
							}
							
							if(nodeSelected == "Constraints")
							{
								mainTab.setSelectedIndex(2);
								innerSpecificationTab.setSelectedIndex(1);
							}
						}
						
					}});
				
				// Tab to tree reflection logic starts
						// to be implemented later
				// logic ends here
				
				leftPanel.setLayout(new BorderLayout());
				leftPanel.add(treeHeaderLabel,BorderLayout.NORTH);
				leftPanel.add(tree,BorderLayout.CENTER);
			
				splitPane.setLeftComponent(leftPanel);
				splitPane.setRightComponent(mainTab);
				
				frame.add(toolBar,BorderLayout.NORTH);
				frame.add(splitPane,BorderLayout.CENTER);
				
				//GUI Part ends
					
				//functionality part begins
				openFileBtn.addActionListener(new ActionListener(){

					@Override
					public void actionPerformed(ActionEvent e) {
				
						String str;
						String spv;
						String str1;
						String str2;
						String strTest;
						String strResults;
						String result; 
						ArrayList <String> constraints = new ArrayList<String>();
						ArrayList <String> pname = new ArrayList<String>();
						ArrayList <String> pvalues = new ArrayList<String>();
						ArrayList <String> testValues = new ArrayList<String>();
						ArrayList <String> tResults = new ArrayList<String>();
						JFileChooser f1 = new JFileChooser();
						
						
						
						
						
						int returnVal = f1.showOpenDialog(frame);
				        if (returnVal == JFileChooser.APPROVE_OPTION)
				        {
				        	File file = f1.getSelectedFile();
				        	BufferedReader br;
				        	try 
				        	{
				        		br = new BufferedReader(new FileReader(file));
				      					
				        		while((str1 = br.readLine())!=null) 
				        		{
				        			// Parameters logic starts
				        			if(str1.startsWith("Parameters:"))
				        			{
				        				while ((str1 = br.readLine()) != null) 
				        				{
				        					if(str1.length()==0)
				        					{
				        						break;
				        					}	//end if

				        					str1 = str1.replace("\"", "");
				        					Pattern paramPattern = Pattern.compile(":");
				        					String[] tokens = paramPattern.split(str1);
				        					str = tokens[0].toString()+"\n";
				        					pname.add(str);
				        					tokens[1] = tokens[1].replace("[", "");
				        					tokens[1] = tokens[1].replace("]", "");
				        					spv = tokens[1].toString()+"\n";
				        					pvalues.add(spv);
				        				} 
				        			} // Parameters logic ends	

				        			if(str1.startsWith("Constraints :"))
				        			{
				        				//System.out.println("Printing the Constraints used:");
				        				while ((str1 = br.readLine()) != null) 
				        				{
				        					//System.out.println(str1);
				        					if(str1.length()==0)
				        					{
				        						break;
				        					}	//end if
				        					
				        					str2 = str1+"\n";
				        					constraints.add(str2);
				        					System.out.println(str1);
				        					System.out.println("*******************");
				        					System.out.println(str2);
				        					System.out.println("/././././...//////");
				        				} // end while
				        			}//end main - if for constraints
				        			
				        			if(str1.startsWith("Tests"))
				        			{
				        				while ((str1 = br.readLine()) != null) 
				        				{
				        					if(str1.length()==0)
				        					{
				        						break;
				        					}	//end if
				        				    strTest = str1+"\n";
				        				    testValues.add(strTest);
				        					
				        				} // end while
				        			} // Test table logic ends	

				      //To add - error msg dialog box
				        			if(str1.startsWith("Test #"))
				        			{
				        				while ((str1 = br.readLine()) != null) 
				        				{
				        					if(str1.length()==0)
				        					{
				        						break;
				        					}	//end if
				        				    Pattern resultPattern = Pattern.compile(",");
				        					String[] tokens = resultPattern.split(str1);
				        					result = tokens[1].toString()+"\n";
				        					tResults.add(result);
				        					
				        				} // end while
				        			} // Test table logic ends	

				        			if(str1.startsWith("Relations :"))
								   {
									//System.out.println("Printing the Relations used:");
									while ((str1 = br.readLine()) != null) 
									{
										if(str1.length()==0)
										{
											break;
										}	//end if
										str1 = str1.replace("\"", "");
										Pattern paramPattern = Pattern.compile(",");
							    		String[] strength = paramPattern.split(str1);
							    		strength[0] = strength[0].replace("[", "");
							    		//int strength_Testset = Integer.parseInt(strength[0]);
							    		//System.out.println(strength1);
							    		if(strength[0]!= null)
							    		{
							    			System.out.println("Strength:" + strength[0]);
							    			//rLabel.setText("Strength of the Test Set:  " + strength[0] );
							    		}
							    		else
							    		{	
							    			JOptionPane.showMessageDialog(frame,"Input file must have Test Strength, Please choose another file");
							    			
							    		}
							    		} // end while
								}//end main - if for relations	
				    			 
				        		
				        		} // end of "While" main 	
				        					        	
				        	//updating the table logic starts

								String[] columnName = {"Constraints"};
								String[] rTableColumnName = {"Test #",testValues.get(0),"Results"};
								//Constraints Table

									constraintsTable.setColumnCount(0);
									constraintsTable.setRowCount(0);	
									
									
									for(int col=0;col<columnName.length;col++)
									{
										constraintsTable.addColumn(columnName[col]);
									}
									
									for(int r=0;r<constraints.size();r++)
									{
										
										constraintsTable.insertRow(r, new Object[]{constraints.get(r)});
									}
								

								// Parameter information Table
									pTable.setColumnCount(0);
									pTable.setRowCount(0);
									
									for(int col=0;col<pnameArray.length;col++)
									{
										pTable.addColumn(pnameArray[col]);
									}
									
									// Adding rows to the table
									for(int row =0;row<pvalues.size();row++)
									{
										pTable.insertRow(row,new Object[]{pname.get(row),pvalues.get(row)});
										//System.out.println(pname.get(row)+"\n"+pvalues.get(row));
									}
									
							   // Test Values table
									testresultTable.setColumnCount(0);
									testresultTable.setRowCount(0);
									
									for(int col=0;col<rTableColumnName.length;col++)
									{
										testresultTable.addColumn(rTableColumnName[col]);
									}
									
									for(int row=0;row<testValues.size();row++)
									{
										
										testresultTable.insertRow(row, new Object[]{row+1,testValues.get(row+1),tResults.get(row)});
										
									}
								

									
				        // updating the table logic ends
				      
				        	} 
				        	
				        	catch (FileNotFoundException e1) 
							{
							// TODO Auto-generated catch block
								e1.printStackTrace();
							} 

				        	
				        	
				        	catch (Exception e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
				        	
				        	
					}
					
						
					
						
					}

					});
				
		
	}
}

	